CIVE 461/861: Urban Transportation Planning
Primary Purpose - Aggregate network performance measures
Secondary Purpose
Differences in individual perceptions of what constitutes the best route: minimizing time, minimizing fuel consumption, or a combination of both?
Solution: Multiple user classes & generalized costs
Knowledge about alternatives varies -> apparently irrational route choices
Solution: Stochastic specifications
Congestion effects affect shorter routes first & make generalized costs comparable to initially less attractive routes
Solution: Congested assignment & equilibrium
Final product is shortest path tree rooted at node \(n_1\)
What is the shortest path from Node 6 to All Others?
Step 1: Cost Table
Node pair | Cost |
---|---|
6,1 | Infinity |
6,2 | Infinity |
6,3 | Infinity |
6,4 | Infinity |
6,5 | Infinity |
6 | 0 |
Step 2: Visitation Table
Node | Visited? |
---|---|
1 | No |
2 | No |
3 | No |
4 | No |
5 | No |
6 | Current |
Step 3: Find neighbors of current node Node 6 neigbors: {1,4,5}
Step 4: Update tentative costs
Node pair | Cost (previous cost) |
---|---|
6,1 | 5 (infinity) |
6,4 | 3 (infinity) |
6,5 | 8 (infinity) |
Costs are less than previous, so update table
\[t=(\frac{L}{S})(1+a(\frac{v}{c})^b)\] \[t=t_0(1+a(\frac{v}{c})^b)\]
Where:
\(t\) = link travel time (min)
\(L\) = link length (mi)
\(S\) = link uncongested average speed (mi/min)
\(t_0\) = free-flow travel speed = L / S
\(v\) = link volume (veh/hr)
\(c\) = link capacity (veh/hr)
\(a\) = parameter = 1.0 if one-hr assignment or 0.15 if 24-hr assignment
\(b\) = parameter = 4 for arterial roads or 6 for freeway
\[t = \begin{cases} t_0(1+a(\frac{v}{c})^b), \frac{v}{c} \leq 1 \\ t_0((1+a-ab)+ab(\frac{v}{c})), \frac{v}{c} > 1 \end{cases}\]
For \(a = 1\) & \(b = 4\), gives \(t=t_0(4(\frac{v}{c})-2)\)
OD trips to be assigned:
A-C = 400
A-D = 200
B-C = 300
B-D = 100
Sum all assigned trips to get complete assignment
\[t_1 = \frac{t_{01}}{1-v_1/c_1}\] where:
\(t_1\) = travel time on link 1
\(t_{01}\) = travel time on link 1 under zero flow condition
\(v_1\) = volume on link 1
\(c_1\) = capacity of link 1
Link | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
\(T_0\) | 10 | 15 | 3 | 5 | 4 |
Capacity | 300 | 500 | 150 | 200 | 200 |
O-D trips to assign:
From/To | 1 | 2 | 3 | 4 |
---|---|---|---|---|
1 | 0 | 100 | 100 | 100 |
2 | 0 | 0 | 50 | 50 |
3 | 0 | 0 | 0 | 100 |
4 | 0 | 0 | 0 | 0 |
Random assignment order:
To | ||
---|---|---|
O-D Pair | 1 | 2 |
(1,2) | 1 | 3 |
(1,3) | 6 | 6 |
(1,4) | 2 | 4 |
(2,3) | 3 | 2 |
(2,4) | 5 | 5 |
(3,4 | 4 | 1 |
Update travel times
O-D pair (1,2) : V (1,2) = 50 | |||||
---|---|---|---|---|---|
Link | 1 | 2 | 3 | 4 | 5 |
V | 50 | 0 | 0 | 0 | 0 |
t | 12 | 15 | 3 | 5 | 4 |
O-D pair (1,4) : V (1,4) = 50 | |||||
Link | 1 | 2 | 3 | 4 | 5 |
V | 100 | 0 | 0 | 50 | 0 |
t | 15 | 15 | 3 | 6.666667 | 4 |
O-D pair (2,3) : V (2,3) = 25 | |||||
Link | 1 | 2 | 3 | 4 | 5 |
V | 100 | 0 | 25 | 50 | 0 |
t | 15 | 15 | 3.6 | 6.666667 | 4 |
O-D pair (3,4) : V (3,4) = 50 | |||||
Link | 1 | 2 | 3 | 4 | 5 |
V | 100 | 0 | 25 | 50 | 50 |
t | 15 | 15 | 3.6 | 6.666667 | 5.333333 |
O-D pair (2,4) : V (2,4) = 25 | |||||
Link | 1 | 2 | 3 | 4 | 5 |
V | 100 | 0 | 25 | 75 | 50 |
t | 15 | 15 | 3.6 | 8 | 5.333333 |
O-D pair (1,3) : V (1,3) = 50 | |||||
Link | 1 | 2 | 3 | 4 | 5 |
V | 100 | 50 | 25 | 75 | 50 |
t | 15 | 16.66667 | 3.6 | 8 | 5.333333 |
Update travel times
O-D pair (3,4) : V (3,4) = 50 | |||||
---|---|---|---|---|---|
Link | 1 | 2 | 3 | 4 | 5 |
V | 100 | 50 | 25 | 75 | 100 |
t | 15 | 16.66667 | 3.6 | 8 | 8 |
O-D pair (2,3) : V (2,3) = 25 | |||||
Link | 1 | 2 | 3 | 4 | 5 |
V | 100 | 50 | 50 | 75 | 100 |
t | 15 | 16.66667 | 4.5 | 8 | 8 |
O-D pair (1,2) : V (1,2) = 50 | |||||
Link | 1 | 2 | 3 | 4 | 5 |
V | 150 | 50 | 50 | 75 | 100 |
t | 20 | 16.66667 | 4.5 | 8 | 8 |
O-D pair (1,4) : V (1,4) = 50 | |||||
Link | 1 | 2 | 3 | 4 | 5 |
V | 150 | 100 | 50 | 75 | 150 |
t | 20 | 18.75 | 4.5 | 8 | 16 |
O-D pair (2,4) : V (2,4) = 25 | |||||
Link | 1 | 2 | 3 | 4 | 5 |
V | 150 | 100 | 50 | 100 | 150 |
t | 20 | 18.75 | 4.5 | 10 | 16 |
Final Flow and Corresponding Travel Time on Links | |||||
O-D pair (1,3) : V (1,3) = 50 | |||||
Link | 1 | 2 | 3 | 4 | 5 |
V | 150 | 150 | 50 | 100 | 150 |
t | 20 | 21.42857 | 4.5 | 10 | 16 |
Must determine link flows {V1, V2} such that \[๐_1+๐_2=๐_๐ด๐ต\] \[๐ก_1=๐ก_2=๐ก^โ\] Where \(t^*\) is the equilibrium travel time between A & B
\[๐น_1=\int_0^{๐ฃ_1^โ} f_1(v_1) dv_1 \] \[๐น_2=\int_0^{v_2^*}f_2(v_2) dv_2 \]
flowchart LR A[P] ---->|1| B(Q) A[P] ---->|2| B(Q) A[P] ---->|3| B(Q)
\[f_1(v_1) = 10(1+0.15(v_1/200)^4)\] \[f_2(v_2) = 20(1+0.15(v_1/400)^4)\] \[f_3(v_3) = 25(1+0.15(v_1/300)^4)\]
Weโll start by creating a Pandas dataframe to store the iteration variables
import pandas as pd
import numpy as np
from scipy.optimize import minimize_scalar
df = pd.DataFrame({"f1": pd.Series(dtype='float'),
"f2": pd.Series(dtype='float'),
"f3": pd.Series(dtype='float'),
"V1": pd.Series(dtype='float'),
"V2": pd.Series(dtype='float'),
"V3": pd.Series(dtype='float'),
"F1": pd.Series(dtype='float'),
"F2": pd.Series(dtype='float'),
"F3": pd.Series(dtype='float'),
"F": pd.Series(dtype='float'),
"lambda": pd.Series(dtype='float')})
We can then define the inputs to the traffic assignment algorithm.
# Specify the freeflow travel times/capacities
ff_tt_1 = 10
ff_tt_2 = 20
ff_tt_3 = 25
C1 = 200
C2 = 400
C3 = 300
volume = 1000 # veh/hr
min_tt = np.min([ff_tt_1, ff_tt_2, ff_tt_3]) # minimum travel time
# Define the volumes on each link (1,2, and 3)
V1 = volume if (ff_tt_1==min_tt) else 0
V2 = volume if (ff_tt_2==min_tt) else 0
V3 = volume if (ff_tt_3==min_tt) else 0
# Define total costs as integrals of travel time costs over volume
F1 = ff_tt_1*V1 + ff_tt_1*0.15/C1**4*V1**5/5
F2 = ff_tt_2*V2 + ff_tt_2*0.15/C2**4*V2**5/5
F3 = ff_tt_3*V3 + ff_tt_3*0.15/C3**4*V3**5/5
F = F1 + F2 + F3
l = 1.0 # intialize lambda to 1.0
tol = 10**-2 # tolerance on the difference in total cost between iterations
row = [ff_tt_1, ff_tt_2, ff_tt_3, V1, V2, V3, F1, F2, F3, F, l]
df.loc[len(df),:] = row # add initial values to df
Next we define the Frank-Wolfe algorithm and solve for \(\lambda\) using scipy optimize minimize_scalar
. The first step is to define a loop that repeatedly calls the minimization on a new set of volumes. We define the Frank-Wolfe algorithm and solve for \(\lambda\) using scipy optimize minimize_scalar
. The next step is to define the optimization problem. Weโll define the optimization in two functions: get_optimal_vals
calculates the various values we need in each iteration and FW_Alg
defines the function to be minized by scipy optimize minimize_scalar
.
# Apply the Frank-Wolfe algorithm on the example dataset
def FW_Alg(x, prev_iter):
f1, f2, f3, V1, V2, V3, F1, F2, F3 = get_optimal_vals(x, prev_iter)
return (F1 + F2 + F3)
# Function computes the various traffic assignment algorithm values at optimality
def get_optimal_vals(x, prev_iter):
f1 = ff_tt_1*(1+0.15*(prev_iter["V1"]/C1)**4)
f2 = ff_tt_2*(1+0.15*(prev_iter["V2"]/C2)**4)
f3 = ff_tt_3*(1+0.15*(prev_iter["V3"]/C3)**4)
min_tt = np.min([f1, f2, f3]) # minimum travel time
V1 = x*prev_iter["V1"] + (1-x)*(volume if f1==min_tt else 0)
V2 = x*prev_iter["V2"] + (1-x)*(volume if f2==min_tt else 0)
V3 = x*prev_iter["V3"] + (1-x)*(volume if f3==min_tt else 0)
F1 = ff_tt_1*V1 + ff_tt_1*0.15/C1**4*V1**5/5
F2 = ff_tt_2*V2 + ff_tt_2*0.15/C2**4*V2**5/5
F3 = ff_tt_3*V3 + ff_tt_3*0.15/C3**4*V3**5/5
return f1, f2, f3, V1, V2, V3, F1, F2, F3
F_diff = F
while F_diff > tol:
F_diff = F
prev_iter = df.iloc[-1] # Get the values from the last iteration
res = minimize_scalar(FW_Alg, args=(prev_iter), bounds=[0,1])
F = res.fun
l = res.x
f1, f2, f3, V1, V2, V3, F1, F2, F3 = get_optimal_vals(l, prev_iter)
row = [f1, f2, f3, V1, V2, V3, F1, F2, F3, F, l]
df.loc[len(df),:] = row
F_diff = F_diff - F
Putting everything together, we can print a table summarizing the variable values at each iteration.
f1 | f2 | f3 | V1 | V2 | V3 | F1 | F2 | F3 | F | lambda | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 10.00 | 20.00 | 25.00 | 1000.00 | 0.00 | 0.00 | 197500.00 | 0.00 | 0.00 | 197500.00 | 1.00 |
1 | 947.50 | 20.00 | 25.00 | 403.46 | 596.54 | 0.00 | 6039.00 | 13701.45 | 0.00 | 19740.44 | 0.40 |
2 | 34.84 | 34.84 | 25.00 | 338.45 | 500.42 | 161.13 | 4217.09 | 10743.87 | 4038.43 | 18999.39 | 0.84 |
3 | 22.30 | 27.35 | 25.31 | 361.97 | 482.63 | 155.41 | 4784.70 | 10266.28 | 3893.55 | 18944.53 | 0.96 |
4 | 26.09 | 26.36 | 25.27 | 354.58 | 472.78 | 172.64 | 4596.77 | 10009.25 | 4330.12 | 18936.14 | 0.98 |
5 | 24.82 | 25.85 | 25.41 | 359.22 | 469.38 | 171.40 | 4713.80 | 9921.62 | 4298.58 | 18934.00 | 0.99 |
6 | 25.61 | 25.69 | 25.40 | 357.30 | 466.87 | 175.83 | 4664.85 | 9857.20 | 4411.38 | 18933.43 | 0.99 |
7 | 25.28 | 25.57 | 25.44 | 358.58 | 465.93 | 175.48 | 4697.45 | 9833.37 | 4402.44 | 18933.27 | 1.00 |